﻿using DFGK.WMS.Common.Extensions;
using DFGK.WMS.Common.Result;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.IRepository.IService;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.Models.PDA;
using Dm;
using Microsoft.EntityFrameworkCore;
using NetTaste;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using Org.BouncyCastle.Bcpg;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using static NPOI.HSSF.Util.HSSFColor;

namespace DFGK_WMS.Repository.Service
{
    public class StackingStorageService : BaseService, IStackingStorageService
    {
        protected readonly static object _lockObj = new object();

        public ITCellRepository TCellRepository { get; }

        ITReceivingOrderDetailRepository tReceivingOrderDetailRepository { get; }
        public DFGK_DB Context { get; }

        public StackingStorageService(ISqlSugarClient client, ITCellRepository tCellRepository, ITReceivingOrderDetailRepository tReceivingOrderDetailRepository, DFGK_DB context) : base(client)
        {
            TCellRepository = tCellRepository;
            this.tReceivingOrderDetailRepository = tReceivingOrderDetailRepository;
            Context = context;
        }

        public bool BuildCreateStackingStorage(out string errMsg, PalletTallyInputModel data)
        {
            errMsg = string.Empty;
            (bool, string, TReceivingOrderDetail) arr = ValidateStatus(data.OrderDetailId);

            if (arr.Item1 == false)
            {
                errMsg = arr.Item2;
                return false;
            }
            TReceivingOrderDetail? item3 = arr.Item3;

            int heightType = (int)EmHeightType.H1150;
            decimal enabledNum = item3.Qty.GetValueOrDefault() - item3.StackedQty.GetValueOrDefault();
            if (enabledNum - data.TotalNum < 0 || data.TotalNum <= 0)
            {
                errMsg = "数量超出，最多还能组" + enabledNum.ToString() + item3.UnitName;
                return false;
            }
            var material = this._Client.Queryable<TMaterial>().InSingle(item3.MaterialId);

            if (material == null)
            {
                errMsg = "未找到物料数据";
                return false;

            }

            if (material.Code != data.PalletPackage.MaterialCode)
            {
                errMsg = "包装信息中的物料与单据物料不一致";
                return false;
            }

            #region 注释
            //if (data.PalletPackages.Select(t => t.MaterialCode).Distinct().Count() > 1)
            //{
            //    errMsg = "物料号存在多种";
            //    return false;
            //    return Result("", ResultCode.Error);
            //}
            //if (data.PalletPackages.Select(t => t.OrderSN).Distinct().Count() > 1 || data.PalletPackages.Select(t => t.OrderLineSN).Distinct().Count() > 1)
            //{
            //    return Result("物料号存在多个订单编号", ResultCode.Error);
            //}
            #endregion
            Model.Models.PalletBindMaterialModel palletBindMaterialModel = new Model.Models.PalletBindMaterialModel()
            {
                PalletBarcode = data.PalletBarcode,
                LogicPartCode = data.LogicPartCode,
                MaterialPackageBindModel = new Model.Models.MaterialPackageBindModel()
                {
                    OrderDetailId = data.OrderDetailId.Value,
                    MaterialCode = data.PalletPackage.MaterialCode,
                    Barcodes = data.PalletPackage.Barcodes,
                    Qty = data.TotalNum,
                }
            };

            TStackingStorage storageModel = _Client.Queryable<TStackingStorage>().First(r => r.Status == 1 && r.PalletBarcode == data.PalletBarcode);
            if (storageModel != null)
            {
                errMsg = "托盘已在组垛中";
                return false;
            }
            string palletBarcode = palletBindMaterialModel.PalletBarcode;
            List<string> palletBarcodeList = palletBarcode.StringToList();
            if (palletBarcodeList != null && palletBarcodeList.Count > 0)
            {
                palletBarcode = palletBarcodeList[0];
                palletBarcodeList.Remove(palletBarcode);
            }
            int OrderId = palletBindMaterialModel.MaterialPackageBindModel.OrderDetailId;
            var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == OrderId);
            decimal? materialNum = 0;
            materialNum = palletBindMaterialModel.MaterialPackageBindModel.Qty;
            try
            {
                int stackingId = 0;
                string LogicPartCode = "";
                _Client.Ado.BeginTran();
                var tackingStorage = _Client.Queryable<TStackingStorage>().First(x => x.PalletBarcode == palletBarcode && x.RelatedOrderDetailId == OrderId && x.WarehouseCode == orderDetail.WarehouseCode && x.Status == 1);
                if (tackingStorage != null && tackingStorage.Id > 0)
                {
                    stackingId = tackingStorage.Id;
                }
                else
                {
                    string errorMsg = "";
                    TCell cell = null;
                    if (cell == null)
                    {
                        errorMsg = "无可用仓位";
                        return false;
                    }
                    var pallet = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == palletBarcode);

                    if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                    {
                        errMsg = "当前托盘不存在";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    if (pallet.Type == (int)PalletTypeEnum.Pallet)
                    {
                        LogicPartCode = "TuoPan";
                    }
                    else if (pallet.Type == (int)PalletTypeEnum.Box64)
                    {
                        LogicPartCode = "Box6040";
                    }
                    else if (pallet.Type == (int)PalletTypeEnum.Box86)
                    {
                        LogicPartCode = "Box8060";
                    }

                    int stackingStorage = _Client.Insertable<TStackingStorage>(new TStackingStorage()
                    {
                        WarehouseName = orderDetail.WarehouseName,
                        WarehouseCode = orderDetail.WarehouseCode,
                        BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                        RelatedOrderDetailId = OrderId,
                        Status = 1,
                        PalletBarcode = palletBarcode,
                        Qty = materialNum,
                        PackQty = 1,
                        AreaCode = "",
                        LogicalPartCode = LogicPartCode,
                        MaterialId = orderDetail.MaterialId,
                        MaterialCode = orderDetail.MaterialCode,
                        MaterialName = orderDetail.MaterialName,
                        CreateUserId = data.UserId,
                        CreateUserName = data.UserName,
                        CreateDate = DateTime.Now,
                        Fifodate = DateTime.Now,
                        ExpectedLocation = cell.Code
                    }).ExecuteCommand();

                    if (stackingStorage <= 0)
                    {
                        errMsg = "保存垛主表数据失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }

                    #region 垛包装数据保存
                    if (palletBarcodeList != null && palletBarcodeList.Count > 0)
                    {
                        foreach (var itemPalletBarcode in palletBarcodeList)
                        {
                            var pallet1 = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == itemPalletBarcode);
                            if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                            {
                                errMsg = "当前托盘不存在";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                            if (pallet.Type == (int)PalletTypeEnum.Pallet)
                            {
                                LogicPartCode = "TuoPan";
                            }
                            else if (pallet.Type == (int)PalletTypeEnum.Box64)
                            {
                                LogicPartCode = "Box6040";
                            }
                            else if (pallet.Type == (int)PalletTypeEnum.Box86)
                            {
                                LogicPartCode = "Box8060";
                            }
                            int chStackingId = _Client.Insertable<TStackingStorage>(new TStackingStorage()
                            {
                                WarehouseName = orderDetail.WarehouseName,
                                WarehouseCode = orderDetail.WarehouseCode,
                                BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                                RelatedOrderDetailId = OrderId,
                                Status = 1,
                                PalletBarcode = itemPalletBarcode,
                                Qty = materialNum,
                                PackQty = 1,
                                AreaCode = "",
                                LogicalPartCode = LogicPartCode,
                                MaterialId = orderDetail.MaterialId,
                                MaterialCode = orderDetail.MaterialCode,
                                MaterialName = orderDetail.MaterialName,
                                CreateUserId = data.UserId,
                                CreateUserName = data.UserName,
                                CreateDate = DateTime.Now,
                                Fifodate = DateTime.Now,
                                ParentPalletBarcode = palletBarcode,
                                ExpectedLocation = cell.Code
                            }).ExecuteCommand();
                            if (chStackingId <= 0)
                            {
                                errMsg = "保存垛主表数据失败";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                        }
                    }

                    /*
                    List<string> barCodes = new List<string>();
                    orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == palletBindMaterialModel.MaterialPackageBindModel.OrderDetailId);

                    TPackageDetail packageContainer = _Client.Queryable<TPackageDetail>().First(x => x.PackageCode == palletBarcode && x.StackingStorageId == stackingId && x.Status == 1 && x.RelatedOrderDetailId == orderDetail.Id);
                    if (packageContainer != null)
                    {
                        //if (palletBindMaterialModel.MaterialPackageBindModel.Barcodes != null && palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count > 0)
                        //{
                        //    packageContainer.HasSkuDetail = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count() > 0;
                        //    packageContainer.SkuNum = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count();
                        //}
                    }
                    else
                    {
                        packageContainer = new TPackageDetail()
                        {
                            Status = 1,
                            RelatedOrderDetailId = orderDetail.Id,
                            MaterialId = orderDetail.MaterialId,
                            MaterialKeyId = orderDetail.MaterialKeyId,
                            MaterialCode = orderDetail.MaterialCode,
                            MaterialName = orderDetail.MaterialName,
                            PackageClass = 1,// package.PackageSkuBindList != null && package.PackageSkuBindList.Count > 0 ? 1 : 2,
                            BatchNo = orderDetail.BatchNo,
                            Qty = palletBindMaterialModel.MaterialPackageBindModel.Qty,
                            UnitId = orderDetail.UnitId,
                            UnitName = orderDetail.UnitName,
                            ConvertFigre = 0,
                            PackageCode = palletBarcode,// package.PackageBarcode
                            StackingStorageId = stackingId,
                            LayerIndex = 1,
                            CreateDate = DateTime.Now,
                            ParentId = 0,
                            IsStocktake = false,
                            CreateUserId = data.UserId.GetValueOrDefault(),
                            CreateUserName = data.UserName,
                        };
                        //if (palletBindMaterialModel.MaterialPackageBindModel.Barcodes != null && palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count > 0)
                        //{
                        //    packageContainer.HasSkuDetail = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count() > 0;
                        //    packageContainer.SkuNum = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count();
                        //}
                        int pkgId = _Client.Insertable<TPackageDetail>(packageContainer).ExecuteCommand();
                        if (pkgId <= 0)
                        {
                            errMsg = "保存组箱数据失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                    }
                    */
                    /* 注释
                    //if (palletBindMaterialModel.MaterialPackageBindModel.Barcodes != null && palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count > 0)
                    //{
                    //    barCodes = palletBindMaterialModel.MaterialPackageBindModel.Barcodes;
                    //    foreach (string barcode in palletBindMaterialModel.MaterialPackageBindModel.Barcodes)
                    //    {
                    //        TPackageDetail sku = new TPackageDetail()
                    //        {
                    //            Status = 1,
                    //            RelatedOrderDetailId = orderDetail.Id,
                    //            MaterialId = orderDetail.MaterialId,
                    //            MaterialKeyId = orderDetail.MaterialKeyId,
                    //            MaterialCode = orderDetail.MaterialCode,
                    //            MaterialName = orderDetail.MaterialName,
                    //            PackageClass = 2,
                    //            BatchNo = orderDetail.BatchNo,
                    //            Qty = 1,
                    //            UnitId = orderDetail.UnitId,
                    //            UnitName = orderDetail.UnitName,
                    //            ConvertFigre = 0,
                    //            Barcode = barcode,
                    //            PackageCode = palletBarcode,
                    //            LayerIndex = 1,
                    //            CreateDate = DateTime.Now,
                    //            StackingStorageId = stackingId,
                    //            ParentId = packageContainer.Id,
                    //            IsStocktake = false,
                    //            CreateUserId = data.UserId.GetValueOrDefault(),
                    //            CreateUserName = data.UserName,
                    //        };
                    //        int skuPkgId = _Client.Insertable<TPackageDetail>(sku).ExecuteCommand();
                    //        if (skuPkgId <= 0)
                    //        {
                    //            errMsg = "保存组箱数据失败";
                    //            _Client.Ado.RollbackTran();
                    //            return false;
                    //        }
                    //    }
                    //}
                    */
                    //更新入库单状态
                    TReceivingOrderDetail? receivingOrderDetail = _Client.Queryable<TReceivingOrderDetail>().First(r => r.Id == OrderId);
                    receivingOrderDetail.StackedQty = orderDetail.StackedQty + materialNum;
                    //Status = 3,
                    receivingOrderDetail.AuditDate = DateTime.Now;
                    receivingOrderDetail.AuditUserId = data.UserId;
                    receivingOrderDetail.AuditUserName = data.UserName;
                    _Client.Updateable<TReceivingOrderDetail>(receivingOrderDetail);

                    //更新货货品明细
                    //if (barCodes.Count > 0)
                    //{

                    //    //List<TReceivingGoodsDetail>? receivingGoodDetailList = _Client.Queryable<TReceivingGoodsDetail>().Where(r => //r.OrderDetailId == OrderId && r.Status == 0 && barCodes.Contains(r.Barcode)).ToList();
                    //    List<TReceivingGoodsDetail>? receivingGoodDetailList = _Client.Queryable<TReceivingGoodsDetail>().Where(r => r.OrderDetailId == OrderId && r.Status == 0 && barCodes.Contains(r.Barcode)).ToList();

                    //    if (receivingGoodDetailList.Count != barCodes.Count)
                    //    {
                    //        errMsg = "货品明细与组垛明细数量不一致";
                    //        _Client.Ado.RollbackTran();
                    //        return false;
                    //    }
                    //    else
                    //    {
                    //        foreach (var item in receivingGoodDetailList)
                    //        {
                    //            item.Status = 1;
                    //            item.PalletBarcode = palletBarcode;
                    //            item.PackageBarcode = palletBarcode;
                    //            _Client.Updateable<TReceivingGoodsDetail>(item);
                    //        }
                    //    }
                    //}

                    #endregion

                    //bool isok = ExecCreateInstruct(out errMsg, orderDetail, station, palletBindMaterialModel);
                    //if (!isok)
                    //{
                    //    return false;
                    //}
                    _Client.Ado.CommitTran();
                }
            }
            catch (Exception)
            {
                errMsg = "保存组箱数据失败";
                _Client.Ado.RollbackTran();
                throw;
            }
            return true;
        }

        public bool BuildCreateStackingStorageEF(out string errMsg, PalletTallyInputModel data)
        {
            errMsg = string.Empty;
            bool result = false;
            (bool, string, TReceivingOrderDetail) arr = ValidateStatusEF(data.OrderDetailId);

            if (arr.Item1 == false)
            {
                errMsg = arr.Item2;
                return false;
            }
            TReceivingOrderDetail? item3 = arr.Item3;

            int heightType = (int)EmHeightType.H1150;
            decimal enabledNum = item3.Qty.GetValueOrDefault() - item3.StackedQty.GetValueOrDefault();
            if (enabledNum - data.TotalNum < 0 || data.TotalNum <= 0)
            {
                errMsg = "数量超出，最多还能组" + enabledNum.ToString() + item3.UnitName;
                return false;
            }
            var material = Context.TMaterials.AsNoTracking().FirstOrDefault(m => m.Id == item3.MaterialId);

            if (material == null)
            {
                errMsg = "未找到物料数据";
                return false;

            }

            if (material.Code != data.PalletPackage.MaterialCode)
            {
                errMsg = "包装信息中的物料与单据物料不一致";
                return false;
            }
            Model.Models.PalletBindMaterialModel palletBindMaterialModel = new Model.Models.PalletBindMaterialModel()
            {
                PalletBarcode = data.PalletBarcode,
                LogicPartCode = data?.LogicPartCode,
                MaterialPackageBindModel = new Model.Models.MaterialPackageBindModel()
                {
                    OrderDetailId = data.OrderDetailId.Value,
                    MaterialCode = data.PalletPackage.MaterialCode,
                    Barcodes = data.PalletPackage.Barcodes,
                    Qty = data.TotalNum,
                }
            };

            TStackingStorage storageModel = Context.TStackingStorages.FirstOrDefault(r => r.Status == 1 && r.PalletBarcode == data.PalletBarcode);
            if (storageModel != null)
            {
                errMsg = "托盘已在组垛中";
                return false;
            }
            string palletBarcode = palletBindMaterialModel.PalletBarcode;
            int OrderId = palletBindMaterialModel.MaterialPackageBindModel.OrderDetailId;
            var orderDetail = Context.TReceivingOrderDetails.FirstOrDefault(x => x.Id == OrderId);
            decimal? materialNum = 0;
            materialNum = palletBindMaterialModel.MaterialPackageBindModel.Qty;
            try
            {
                int stackingId = 0;
                string LogicPartCode = "";
                var tackingStorage = Context.TStackingStorages.FirstOrDefault(x => x.PalletBarcode == palletBarcode && x.RelatedOrderDetailId == OrderId && x.WarehouseCode == orderDetail.WarehouseCode && x.Status == 1);
                if (tackingStorage != null && tackingStorage.Id > 0)
                {
                    stackingId = tackingStorage.Id;
                }
                else
                {

                    var pallet = Context.TPallets.FirstOrDefault(x => x.PalletBarcode == palletBarcode);

                    if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                    {
                        errMsg = "当前托盘不存在";
                        return false;
                    }
                    if (pallet.Type == (int)PalletTypeEnum.Pallet)
                    {
                        LogicPartCode = "TuoPan";
                    }
                    else if (pallet.Type == (int)PalletTypeEnum.Box64)
                    {
                        LogicPartCode = "Box6040";
                    }
                    else if (pallet.Type == (int)PalletTypeEnum.Box86)
                    {
                        LogicPartCode = "Box8060";
                    }

                    TStackingStorage chStacking = new TStackingStorage();
                    #region 垛包装数据保存
                    if (palletBarcode != null)
                    {
                        chStacking.WarehouseName = orderDetail.WarehouseName;
                        chStacking.WarehouseCode = orderDetail.WarehouseCode;
                        chStacking.BillType = (int)orderDetail.BillType.GetValueOrDefault();
                        chStacking.RelatedOrderDetailId = OrderId;
                        chStacking.Status = 1;
                        chStacking.PalletBarcode = palletBarcode;
                        chStacking.Qty = materialNum;
                        chStacking.PackQty = 1;
                        chStacking.AreaCode = "";
                        chStacking.LogicalPartCode = LogicPartCode;
                        chStacking.MaterialId = orderDetail.MaterialId;
                        chStacking.MaterialCode = orderDetail.MaterialCode;
                        chStacking.MaterialName = orderDetail.MaterialName;
                        chStacking.CreateUserId = data.UserId;
                        chStacking.CreateUserName = data.UserName;
                        chStacking.CreateDate = DateTime.Now;
                        chStacking.Fifodate = DateTime.Now;
                        chStacking.ParentPalletBarcode = palletBarcode;
                        //chStacking.ExpectedLocation = cell.Code;
                        Context.TStackingStorages.Add(chStacking);
                        if (Context.SaveChanges() <= 0)
                        {
                            errMsg = "保存垛主表数据失败";
                            return false;
                        }
                        stackingId = chStacking.Id;
                    }

                    TCell allocateCell = null;
                    if (allocateCell == null)
                    {
                        errMsg = "无可用仓位";
                        return false;
                    }

                    //更新托盘
                    var pall = Context.TPallets.FirstOrDefault(p => p.Id == pallet.Id);
                    pall.WarehouseId = allocateCell.Id;
                    pall.LocationCode = allocateCell.Code;
                    pall.LocationName = allocateCell.Name;
                    pall.ErplocationName = allocateCell.Erpcode;
                    pall.ModifyDate = DateTime.Now;
                    Context.TPallets.Update(pall);
                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "更新托盘货位信息失败";
                        return false;
                    }


                    int? fullStatus = null;
                    if (orderDetail.BillType == (int)EmInBillType.EmptyPalletIn)
                    {
                        fullStatus = 3;
                    }
                    else
                    {
                        fullStatus = 1;
                    }

                    //锁仓位
                    var cell = Context.TCells.AsNoTracking().FirstOrDefault(x => x.Id == allocateCell.Id);
                    cell.BusinessType = (int)EmBusinessType.In;
                    cell.IsLock = true;
                    cell.FullStatus = (int)fullStatus;
                    cell.Status = (int)EmCellStatus.Lock;
                    cell.ModifyDate = DateTime.Now;
                    Context.TCells.Update(cell);

                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "仓位锁定失败";
                        return false;
                    }
                    var updTss = Context.TStackingStorages.Find(chStacking.Id);
                    if (updTss == null)
                    {
                        errMsg = "找不到";
                        return false;
                    }
                    updTss.ExpectedLocation = cell.Code;
                    Context.TStackingStorages.Update(updTss);
                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "保存垛主表数据失败";
                        return false;
                    }

                    //更新入库单状态
                    TReceivingOrderDetail? receivingOrderDetail = Context.TReceivingOrderDetails.FirstOrDefault(r => r.Id == OrderId);
                    receivingOrderDetail.StackedQty = data.TotalNum;
                    //Status = 3,
                    receivingOrderDetail.AuditDate = DateTime.Now;
                    receivingOrderDetail.AuditUserId = data.UserId;
                    receivingOrderDetail.AuditUserName = data.UserName;
                    Context.TReceivingOrderDetails.Update(receivingOrderDetail);
                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "更新入库单失败";
                        return false;
                    }
                    #endregion
                }
                result = stackingId > 0;
                if (!result)
                {
                    errMsg = "保存垛主表数据失败";
                    return false;
                }
            }
            catch (Exception)
            {
                errMsg = "保存组箱数据失败";
                throw;
            }
            return true;
        }

        private (bool, string, TReceivingOrderDetail) ValidateStatus(int? orderDetailId)
        {
            TReceivingOrderDetail orderDetail = _Client.Queryable<TReceivingOrderDetail>().InSingle(orderDetailId);

            if (orderDetail == null)
            {
                return (false, "未找到入库单", null);
            }
            if (orderDetail.Status == 0 || orderDetail.Status == 1)
            {
                return (false, "入库单未审核", null);
            }
            if (orderDetail.Status == 4 || orderDetail.Status == 5)
            {
                return (false, "入库单已完成", null);
            }

            if (orderDetail.Status != 2 && orderDetail.Status != 3)
            {
                return (false, "入库单状态有误", null);
            }
            return (true, string.Empty, orderDetail);
        }
        private (bool, string, TReceivingOrderDetail) ValidateStatusEF(int? orderDetailId)
        {
            var orderObj = Context.TReceivingOrderDetails.Find(orderDetailId);
            if (orderObj == null)
            {
                return (false, "未找到入库单", null);
            }
            TReceivingOrderDetail orderDetail = orderObj;

            if (orderDetail.Status == 0 || orderDetail.Status == 1)
            {
                return (false, "入库单未审核", null);
            }
            if (orderDetail.Status == 4 || orderDetail.Status == 5)
            {
                return (false, "入库单已完成", null);
            }

            if (orderDetail.Status != 2 && orderDetail.Status != 3)
            {
                return (false, "入库单状态有误", null);
            }
            return (true, string.Empty, orderDetail);
        }

        /// <summary>
        /// 开始入库
        /// </summary>
        /// <param name="errorMsg"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool ExecCreateInstruct(out string errorMsg, params object[] data)
        {
            errorMsg = "";
            if (data == null || data.Length < 3)
            {
                errorMsg = "参数错误";
                return false;
            }
            TReceivingOrderDetail orderDetail = data[0] as TReceivingOrderDetail;
            int heightType = (int)EmHeightType.H1150;
            Model.Models.PalletBindMaterialModel palletBind = data[2] as Model.Models.PalletBindMaterialModel;
            if (orderDetail == null || palletBind == null)
            {
                errorMsg = "参数错误";
                return false;
            }

            TInstruct instruct = null;
            List<string> packageBarcodes = new List<string>();
            //更新收货单明细表的组垛数量、保存垛主表信息、修改垛明细表的垛主表主键id
            string palletBarcode = palletBind.PalletBarcode;
            int cellId;
            TCell allocateCell = null;
            decimal? materialNum = 0;
            decimal? price = 0;
            lock (_lockObj)
            {
                bool result = false;
                TPallet pallet = null;
                _Client.Ado.BeginTran();
                bool invCount = _Client.Queryable<TInventory>().Any(x => x.Status == 1 && x.PalletBarcode == palletBarcode);
                if (invCount)
                {
                    errorMsg = "当前垛已经存在库存";
                    return false;
                }
                if (orderDetail.Status == (int)EmBillStatus.Create)
                {
                    errorMsg = "入库单未启动";
                    return false;
                }
                if (orderDetail.Status == (int)EmBillStatus.Finished || orderDetail.Status == (int)EmBillStatus.MandatoryFinished)
                {
                    errorMsg = "入库单已完成";
                    return false;
                }
                if (orderDetail.Status != (int)EmBillStatus.Executing)
                {
                    errorMsg = "当前入库单未执行";
                    return false;
                }
                if (orderDetail.Price.HasValue)
                {
                    price = orderDetail.Price;
                }
                bool outInstructCount = _Client.Queryable<TInstruct>().Any(x => x.WarehouseCode == orderDetail.WarehouseCode && x.Status == 2 && x.BusinessType == (int)EmBusinessType.Out && x.IsSuspend == false);
                if (outInstructCount)
                {
                    errorMsg = "有出库指令未完成，不能执行入库";
                    return false;
                }
                TMaterial material = _Client.Queryable<TMaterial>().First(x => x.Id == orderDetail.MaterialId);
                if (material == null)
                {
                    errorMsg = "订单明细物料数据不存在";
                    return false;
                }
                pallet = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == palletBarcode);
                if (pallet == null)
                {
                    errorMsg = "该托盘未维护";
                    return false;
                }
                if (pallet.Status == 0)
                {
                    errorMsg = "该托盘已被禁用";
                    return false;
                }
                //TStrategy strategy;
                //strategy = _Client.Queryable<TStrategy>().First(x => x.IsEnable == true && x.StrategyType == 1 && x.IsUsed == true);
                //if (strategy == null)
                //{
                //    errorMsg = "未启用策略";
                //    return false;
                //}



                var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.MaterialId == orderDetail.MaterialId && s.WarehouseCode == orderDetail.WarehouseCode && s.RelatedOrderDetailId == orderDetail.Id && s.PalletBarcode == palletBarcode);


                if (stackingStorage == null || string.IsNullOrEmpty(stackingStorage.LogicalPartCode))
                {
                    errorMsg = "未选择逻辑分区";
                    return false;
                }
                if (stackingStorage.LogicalPartCode == "Box8060" && pallet.Type != 1)
                {
                    errorMsg = "逻辑分区与料箱不匹配";
                    return false;
                }
                else if (stackingStorage.LogicalPartCode == "Box6040" && pallet.Type != 2)
                {
                    errorMsg = "逻辑分区与料箱不匹配";
                    return false;
                }
                var stackingstorage = _Client.Queryable<TStackingStorage>().First(x => x.PalletBarcode == palletBarcode);
                allocateCell = _Client.Queryable<TCell>().First(c => c.Code == stackingstorage.ExpectedLocation);
                //allocateCell = TCellRepository.AllocateCell(srcStation, (int)orderDetail.MaterialId, (int)orderDetail.MaterialKeyId, orderDetail.QualityState, heightType, out errorMsg, stackingStorage.LogicalPartCode);
                //if (allocateCell == null)
                //{
                //    errorMsg = "无可用仓位";
                //    return false;
                //}
                //cellId = allocateCell.Id;
                decimal? putawayQTY = _Client.Queryable<TPutawayOrder>().Where(p => p.SourceType == 1 && p.RelatedOrderDetailId == orderDetail.Id).Sum(t => t.Qty).GetValueOrDefault();
                //最小库存单位
                materialNum = palletBind.MaterialPackageBindModel.Qty;
                //   int boxNum = palletBind.MaterialPackageBindModels.Where(t => t != null).Sum(t => t.PackageCount);
                _Client.Ado.BeginTran();
                bool hasSkuDetail = true;
                int stackingStorageId = _Client.Queryable<TStackingStorage>().First(s => s.PalletBarcode == palletBarcode && s.MaterialId == orderDetail.MaterialId && s.WarehouseCode == orderDetail.WarehouseCode && s.RelatedOrderDetailId == orderDetail.Id).Id;

                //更新托盘
                //var pall =  _Client.Queryable<TPallet>().First(p => p.Id == pallet.Id);
                //pall.WarehouseId = allocateCell.Id;
                //pall.LocationCode = allocateCell.Code;
                //pall.LocationName = allocateCell.Name;
                //pall.ErplocationName = allocateCell.Erpcode;
                //pall.ModifyDate = DateTime.Now;
                //int count = _Client.Updateable<TPallet>(pall).ExecuteCommand();
                //if (count <= 0)
                //{
                //    errorMsg = "更新托盘货位信息失败";
                //    _Client.Ado.RollbackTran();
                //    return false;
                //}
                var receivingOrderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == orderDetail.Id);
                //receivingOrderDetail.StackedQty = putawayQTY + materialNum;
                //if (string.IsNullOrWhiteSpace(stackingStorage.ParentPalletBarcode))
                //{
                //    //更新入库单明细 库存数量
                //    int count = _Client.Updateable<TReceivingOrderDetail>(receivingOrderDetail).ExecuteCommand();
                //    if (count <= 0)
                //    {
                //        errorMsg = "叠盘完成时，更新收货单的组垛数据失败";
                //        _Client.Ado.RollbackTran();
                //        return false;
                //    }
                //}
                //int? fullStatus = null;
                //if (orderDetail.BillType == (int)EmInBillType.EmptyPalletIn)
                //{
                //    fullStatus = 3;
                //}
                //else
                //{
                //    fullStatus = 1;
                //}

                //锁仓位
                //var cell = _Client.Queryable<TCell>().First(x => x.Id == allocateCell.Id);
                //cell.BusinessType = (int)EmBusinessType.In;
                //cell.IsLock = true;
                //cell.FullStatus = (int)fullStatus;
                //cell.Status = (int)EmCellStatus.Lock;
                //cell.ModifyDate = DateTime.Now;
                //count = _Client.Updateable<TCell>(cell).ExecuteCommand();

                //if (count <= 0)
                //{
                //    errorMsg = "仓位锁定失败";
                //    _Client.Ado.RollbackTran();
                //    return false;
                //}
                //不用修改入库垛信息仓位了已经分配了
                //var stackingstorage = _Client.Queryable<TStackingStorage>().First(x => x.PalletBarcode == palletBarcode);
                //stackingstorage.ExpectedLocation = allocateCell.Code;
                //count = _Client.Updateable<TStackingStorage>(stackingstorage).ExecuteCommand();
                //if (count <= 0)
                //{
                //    errorMsg = "分配的收货仓位失败";
                //    _Client.Ado.RollbackTran();
                //    return false;
                //}

                //生成wms指令
                instruct = new TInstruct
                {
                    Status = 2,
                    ToLocation = "",
                    StackingStorageId = stackingStorageId,
                    WorkDeviceType = 2,
                    InstructType = 0,
                    Action = 0,
                    RelatedOrderDetailId = orderDetail.Id,
                    DeviceCode = "",
                    ExpectedToLocation = allocateCell.Code,
                    InstructIndex = 1,
                    PalletBarcode = palletBarcode,
                    ScanedBarcode = palletBarcode,
                    Priority = 9999,
                    Qty = (decimal)materialNum,
                    FinishedQty = 0,
                    StartTime = DateTime.Now,
                    BusinessGroupId = Guid.NewGuid(),
                    BusinessType = (int)EmBusinessType.In,
                    BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                    LogicalCellAddr = allocateCell.Erpcode
                };
                int instructId = _Client.Insertable<TInstruct>(instruct).ExecuteReturnIdentity();

                if (instructId <= 0)
                {
                    errorMsg = "指令保存失败";
                    _Client.Ado.RollbackTran();
                    return false;
                }
                instruct.Id = instructId;

                //保存库存
                TInventory inventory = new TInventory()
                {
                    WarehouseId = allocateCell.WhId,
                    WarehouseCode = allocateCell.WhCode,
                    WarehouseName = allocateCell.WhName,
                    //CompanyId = order.CompanyId,
                    //CompanyName = order.CompanyName,
                    LocationId = allocateCell.Id,
                    LocationCode = allocateCell.Code,
                    LocationDepth = allocateCell.DepthIndex,
                    LocationName = allocateCell.Name,
                    Status = 3,
                    //TaskId = instructs[0].TaskId,
                    PalletBarcode = palletBarcode,
                    ParentPalletBarcode = stackingStorage.ParentPalletBarcode,
                    //RelatedOrderId = orderDetail.OrderId,
                    RelatedOrderDetailId = orderDetail.Id,
                    BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                    IsLock = true,
                    CreateDate = DateTime.Now,
                    MaterialId = orderDetail.MaterialId,
                    MaterialCode = orderDetail.MaterialCode,
                    MaterialName = orderDetail.MaterialName,
                    HasSkuDetail = hasSkuDetail,
                    PutawayQty = materialNum,
                    UnitId = orderDetail.UnitId,
                    UnitName = orderDetail.UnitName,
                    ExpireDate = orderDetail.ExpireDate,
                    ProductDate = orderDetail.ProductDate,
                    SupplierId = orderDetail.SupplierId,
                    SupplierName = orderDetail.SupplierName,
                    MaterialTypeCode = orderDetail.MaterialTypeCode,
                    MaterialTypeName = orderDetail.MaterialTypeName,
                    PickedQty = 0,
                    PackQty = packageBarcodes.Count,
                    ErplocationCode = allocateCell.Erpcode,
                    StackingStorageId = stackingStorageId,
                    LocationHeightType = allocateCell.HeightType,
                    RealHeightType = heightType,
                    LocationColumnNo = allocateCell.ColumnNo,
                    LocationLayerNo = allocateCell.LayerNo,
                    LocationDistanceValue = allocateCell.DistanceValue,
                    LocationLineNo = allocateCell.LineNo,
                    TotalPrice = price * materialNum,
                    Price = price,
                    AvailableQty = palletBind.MaterialPackageBindModel.Qty,
                    AllocateQty = 0
                };
                var inventoryId = _Client.Insertable<TInventory>(inventory).ExecuteReturnBigIdentity();
                if (inventoryId <= 0)
                {
                    errorMsg = "库存主表保存失败";
                    _Client.Ado.RollbackTran();
                    return false;
                }
                #region 保存库存流水注释
                ////保存库存流水
                //TInventoryLog inventoryLog = new TInventoryLog()
                //{
                //    SourceType = 0,
                //    SourceSn = orderDetail.OrderSn,
                //    WarehouseId = orderDetail.WarehouseId,
                //    WarehouseName = orderDetail.WarehouseName,
                //    AreaName = inventory.AreaName,
                //    AreaId = inventory.AreaId,
                //    LocationCode = inventory.LocationCode,
                //    PalletBarcode = instruct.PalletBarcode,
                //    OwnerId = orderDetail.OwnerId,
                //    OwnerName = orderDetail.OwnerName,
                //    MaterialId = orderDetail.MaterialId,
                //    MaterialCode = orderDetail.MaterialCode,
                //    MaterialName = orderDetail.MaterialName,
                //    BatchNo = orderDetail.BatchNo,
                //    StartQty = 0,
                //    ChangeQty = instruct.Qty,
                //    EndQty = instruct.Qty,
                //    BaseUnitId = orderDetail.UnitId,
                //    BaseUnitName = orderDetail.UnitName,
                //    CreateDate = DateTime.Now,
                //};
                //int logId = _Client.Insertable<TInventoryLog>(inventoryLog).ExecuteReturnIdentity();
                //if (logId < 0)
                //{
                //    errorMsg = "库存日志表保存失败";
                //    _Client.Ado.RollbackTran();
                //    return false;
                //}
                #endregion
                //保存上架单主表
                Random random = new Random(Guid.NewGuid().GetHashCode());
                int randNum = random.Next(1, 10000);
                string str = DateTime.Now.ToString("yyyyMMddHHmmssfff") + randNum.ToString("0000");
                string putawayCode = "PUT" + str;
                TPutawayOrder putawayOrder = new TPutawayOrder()
                {
                    Code = putawayCode,
                    RelatedOrderDetailId = orderDetail.Id,
                    StackingStorageId = stackingStorageId,
                    PalletBarcode = palletBarcode,
                    ParentPalletBarcode = stackingStorage.ParentPalletBarcode,
                    LocationCode = allocateCell.Code,
                    LocationDepth = allocateCell.DepthIndex == 0 ? null : allocateCell.DepthIndex,
                    Status = 4,
                    Qty = materialNum,
                    CreateDate = DateTime.Now,
                    MaterialId = orderDetail.MaterialId,
                    MaterialCode = orderDetail.MaterialCode,
                    MaterialName = orderDetail.MaterialName,
                    CreateUserId = 0,
                    CreateUserName = "系统",
                    SourceType = 1,
                };

                var putId = _Client.Insertable<TPutawayOrder>(putawayOrder).ExecuteReturnBigIdentity();
                if (putId <= 0)
                {
                    errorMsg = "上架单主表保存失败";
                    _Client.Ado.RollbackTran();
                    return false;
                }
                if (palletBind.MaterialPackageBindModel.Barcodes != null && palletBind.MaterialPackageBindModel.Barcodes.Count > 0)
                {

                    List<TPackageDetail> packageDetailList = _Client.Queryable<TPackageDetail>().Where(p => p.RelatedOrderDetailId == orderDetail.Id && p.StackingStorageId == stackingStorageId && p.PackageCode == palletBarcode).ToList();
                    var packageDetail = packageDetailList.FirstOrDefault(t => t.PackageClass == 1 && t.ParentId == 0);
                    foreach (var item in palletBind.MaterialPackageBindModel.Barcodes)
                    {
                        //库存明细保存
                        TInventoryDetail inventoryDetail = new TInventoryDetail()
                        {
                            InventoryId = (int)inventoryId,
                            Barcode = item,
                            PackageBarcode = palletBarcode,
                            PalletBarcode = palletBarcode,
                            CreateDate = DateTime.Now,
                            SkuNum = 1,
                            Price = price,
                            TotalPrice = price * 1,
                            IsSku = true,
                        };

                        var inventoryDetailId = _Client.Insertable<TInventoryDetail>(inventoryDetail).ExecuteReturnBigIdentity();
                        if (inventoryDetailId <= 0)
                        {
                            errorMsg = "库存明细表保存失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                        //上架单明细表保存
                        TPutawayOrderDetail putawaydetail = new TPutawayOrderDetail()
                        {
                            PutawayOrderId = (int)putId,
                            PalletBarcode = palletBarcode,
                            PackageBarcode = palletBarcode,// package.PackageBarcode
                            MaterialBarcode = item,
                        };
                        var putDetailId = _Client.Insertable<TPutawayOrderDetail>(putawaydetail).ExecuteReturnBigIdentity();
                        if (putDetailId < 0)
                        {
                            errorMsg = "上架单明细表保存失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                        if (packageDetail != null)
                        {
                            if (packageDetailList.Any(t => t.Barcode == item))
                            {
                                continue;
                            }
                            TPackageDetail package = new TPackageDetail()
                            {
                                Status = 1,
                                RelatedOrderDetailId = orderDetail.Id,
                                MaterialId = orderDetail.MaterialId,
                                MaterialCode = orderDetail.MaterialCode,
                                MaterialName = orderDetail.MaterialName,
                                PackageClass = 2,
                                Qty = 1,
                                UnitId = orderDetail.UnitId,
                                UnitName = orderDetail.UnitName,
                                ConvertFigre = 0,
                                Barcode = item,
                                PackageCode = palletBarcode,
                                LayerIndex = 1,
                                CreateDate = DateTime.Now,
                                StackingStorageId = stackingStorageId,
                                ParentId = packageDetail.Id,
                                IsStocktake = false,
                                CreateUserId = packageDetail.CreateUserId,
                                CreateUserName = packageDetail.CreateUserName,
                            };
                            var skuPkgId = _Client.Insertable<TPackageDetail>(package).ExecuteReturnBigIdentity();
                            if (skuPkgId <= 0)
                            {
                                errorMsg = "保存组箱数据失败";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                        }
                    }
                    //更新入库单货品明细
                    var receivingGoodDetailList = _Client.Queryable<TReceivingGoodsDetail>().Where(r => r.OrderDetailId == orderDetail.Id && palletBind.MaterialPackageBindModel.Barcodes.Contains(r.Barcode)).ToList();
                    if (receivingGoodDetailList.Count != palletBind.MaterialPackageBindModel.Barcodes.Count)
                    {
                        errorMsg = "货品明细与组垛明细数量不一致";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    else
                    {
                        foreach (var item in receivingGoodDetailList)
                        {
                            item.Status = 1;
                            item.PalletBarcode = palletBarcode;
                            item.PackageBarcode = palletBarcode;
                            _Client.Updateable<TReceivingGoodsDetail>(item);
                        }
                    }
                }
                else
                {
                    //库存明细保存
                    TInventoryDetail inventoryDetail = new TInventoryDetail()
                    {
                        InventoryId = (int)inventoryId,
                        Barcode = "",
                        PackageBarcode = palletBarcode,// package.PackageBarcode
                        PalletBarcode = palletBarcode,
                        CreateDate = DateTime.Now,
                        SkuNum = materialNum,
                        IsSku = false,
                        Price = price,
                        TotalPrice = price * materialNum
                    };
                    var inventoryDetailId = _Client.Insertable<TInventoryDetail>(inventoryDetail).ExecuteReturnBigIdentity();
                    if (inventoryDetailId < 0)
                    {
                        errorMsg = "库存明细表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    //上架单明细表保存
                    TPutawayOrderDetail putawayOrderDetail = new TPutawayOrderDetail()
                    {
                        PutawayOrderId = (int)putId,
                        PalletBarcode = palletBarcode,
                        PackageBarcode = palletBarcode,//package.PackageBarcode
                        MaterialBarcode = "",
                    };
                    var putDetailId = _Client.Insertable<TPutawayOrderDetail>(putawayOrderDetail).ExecuteReturnBigIdentity();

                    if (putDetailId < 0)
                    {
                        errorMsg = "上架单明细表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }

                }
                if (receivingOrderDetail.Qty == receivingOrderDetail.StackedQty)
                {
                    var isok = ExecInstructFinished(instruct, out errorMsg);
                    if (!isok)
                    {
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                }
                _Client.Ado.CommitTran();
                return true;
            }
        }

        /// <summary>
        /// 完成入库
        /// </summary>
        /// <param name="instruct"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        private bool ExecInstructFinished(TInstruct instruct, out string errorMsg)
        {
            errorMsg = "";
            if (string.IsNullOrEmpty(instruct.PalletBarcode))
            {
                errorMsg = "参数错误";
                return false;
            }
            lock (_lockObj)
            {
                try
                {
                    var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(r => r.Id == instruct.RelatedOrderDetailId);
                    if (orderDetail == null)
                    {
                        errorMsg = "入库单明细不存在";
                        return false;
                    }
                    var inventory = _Client.Queryable<TInventory>().First(i => i.RelatedOrderDetailId == orderDetail.Id && i.LocationCode == instruct.ExpectedToLocation && i.PalletBarcode == instruct.PalletBarcode && i.Status == 3);
                    if (inventory == null)
                    {
                        errorMsg = "库存数据不存在";
                        return false;
                    }
                    List<TInventoryDetail> inventoryDetailList = _Client.Queryable<TInventoryDetail>().Where(i => i.InventoryId == inventory.Id).ToList();
                    if (inventoryDetailList == null || inventoryDetailList.Count == 0)
                    {
                        errorMsg = "库存明细数据不存在";
                        return false;
                    }
                    List<string> packageBarcodes = inventoryDetailList.Select(t => t.PackageBarcode).Distinct().ToList();
                    TCell cell = _Client.Queryable<TCell>().First(c => c.Code == instruct.ExpectedToLocation);
                    if (cell == null)
                    {
                        errorMsg = "仓位数据不存在";
                        return false;
                    }
                    DateTime? now = DateTime.Now;
                    bool result = false;
                    #region 事务处理
                    _Client.Ado.BeginTran();
                    result = _Client.Insertable<TInstruct>(instruct).ExecuteCommandIdentityIntoEntity();
                    if (!result)
                    {
                        _Client.Ado.RollbackTran();
                        errorMsg = "指令插入失败";
                        return false;
                    }
                    var putawayOrder = _Client.Queryable<TPutawayOrder>().First(p => p.Status == 4 && p.RelatedOrderDetailId == orderDetail.Id && p.StackingStorageId == instruct.StackingStorageId);
                    putawayOrder.Status = 5;
                    putawayOrder.Fifodate = now;
                    var count = _Client.Updateable<TPutawayOrder>(putawayOrder).ExecuteCommand();
                    if (count <= 0)
                    {
                        errorMsg = "上架单状态修改失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }

                    var inventory1 = _Client.Queryable<TInventory>().First(i => i.Id == inventory.Id);
                    inventory1.Status = 1;
                    inventory1.AllocateQty = instruct.Qty;
                    inventory1.InStockDate = now;
                    inventory1.InStockShortDate = Convert.ToInt32(now.Value.ToString("yyyyMMdd"));
                    inventory1.PutawayQty = instruct.Qty;
                    inventory1.IsLock = false;
                    count = _Client.Updateable<TInventory>(inventory1).ExecuteCommand();
                    if (count <= 0)
                    {
                        errorMsg = "库存状态修改失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    var cell1 = _Client.Queryable<TCell>().First(c => c.Id == inventory.LocationId);
                    cell1.IsLock = false;
                    cell1.BusinessType = 0;
                    cell1.Status = 1;
                    cell1.ModifyDate = now;
                    count = _Client.Updateable<TCell>(cell1).ExecuteCommand();
                    if (count <= 0)
                    {
                        errorMsg = "仓位状态修改失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    //查询组垛
                    bool isUpdateOrderDetail = true;
                    List<string> palletBarcodes = new List<string>();
                    var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.Status == 1 && s.PalletBarcode == inventory.PalletBarcode);
                    List<TStackingStorage> stackingStorageModels = _Client.Queryable<TStackingStorage>().Where(s => s.Status == 1 && (s.PalletBarcode == stackingStorage.PalletBarcode || s.ParentPalletBarcode == stackingStorage.PalletBarcode)).ToList();
                    if (stackingStorageModels.Count > 1)
                    {
                        //拆卸
                        palletBarcodes = stackingStorageModels.Select(t => t.PalletBarcode).Distinct().ToList();
                        count = _Client.Queryable<TInventory>().Where(i => i.Status == 1 && i.IsLock == false && palletBarcodes.Contains(i.PalletBarcode)).Count();
                        if (palletBarcodes.Count == count)
                        {
                            isUpdateOrderDetail = true;
                        }
                        else
                        {
                            isUpdateOrderDetail = false;
                        }
                    }
                    if (isUpdateOrderDetail)
                    {
                        decimal? totalPutawayQTY = _Client.Queryable<TPutawayOrder>().Where(t => t.SourceType == 1 && t.RelatedOrderDetailId == orderDetail.Id && t.Status == 5).Sum(t => t.Qty);
                        TReceivingOrderDetail modifyOrderDetail = new TReceivingOrderDetail
                        {
                            ReceivedQty = totalPutawayQTY,
                            InStarDate = orderDetail.InStarDate == null ? now : orderDetail.InStarDate,
                        };
                        if (totalPutawayQTY.GetValueOrDefault() >= orderDetail.Qty.GetValueOrDefault())
                        {
                            modifyOrderDetail.Status = (int)EmBillStatus.Finished;
                        }

                        var receivingOrderDetail = _Client.Queryable<TReceivingOrderDetail>().First(r => r.Id == orderDetail.Id);
                        receivingOrderDetail.ReceivedQty = modifyOrderDetail.ReceivedQty;
                        receivingOrderDetail.InStarDate = modifyOrderDetail.InStarDate;
                        receivingOrderDetail.Status = modifyOrderDetail.Status;
                        count = _Client.Updateable<TReceivingOrderDetail>(receivingOrderDetail).ExecuteCommand();
                        if (count <= 0)
                        {
                            errorMsg = "订单明细修改失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                    }
                    //保存库存日志表
                    //int logId = inventoryLogService.InsertInventoryLog(context, 
                    TInventoryLog inventoryLog = new TInventoryLog()
                    {
                        SourceType = 0,
                        SourceSn = orderDetail.OrderSn,
                        WarehouseId = orderDetail.WarehouseId,
                        WarehouseName = orderDetail.WarehouseName,
                        LocationCode = inventory.LocationCode,
                        PalletBarcode = instruct.PalletBarcode,
                        MaterialId = orderDetail.MaterialId,
                        MaterialCode = orderDetail.MaterialCode,
                        MaterialName = orderDetail.MaterialName,
                        StartQty = 0,
                        ChangeQty = instruct.Qty,
                        EndQty = instruct.Qty,
                        BaseUnitId = orderDetail.UnitId,
                        BaseUnitName = orderDetail.UnitName,
                        CreateDate = DateTime.Now,
                    };
                    int logId = _Client.Insertable<TInventoryLog>(inventoryLog).ExecuteReturnIdentity();
                    if (logId < 0)
                    {
                        errorMsg = "库存日志表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    _Client.Ado.CommitTran();
                    return true;
                    #endregion
                }
                catch (Exception)
                {
                    _Client.Ado.RollbackTran();
                    throw;
                }
            }
        }

        /// <summary>
        /// 获取一个仓位
        /// </summary>
        /// <returns></returns>
        private TCell GetOneCell(out string errorMsg, Model.Models.PalletBindMaterialModel palletBindMaterialModel)
        {
            errorMsg = "";
            var stackingStorage = Context.TStackingStorages.FirstOrDefault(s => s.PalletBarcode == palletBindMaterialModel.PalletBarcode);
            var pallet = Context.TPallets.FirstOrDefault(x => x.PalletBarcode == palletBindMaterialModel.PalletBarcode);

            if (stackingStorage == null || string.IsNullOrEmpty(stackingStorage.LogicalPartCode))
            {
                errorMsg = "未选择逻辑分区";
                return null;
            }
            if (stackingStorage.LogicalPartCode == "Box8060" && pallet.Type != 1)
            {
                errorMsg = "逻辑分区与料箱不匹配";
                return null;
            }
            else if (stackingStorage.LogicalPartCode == "Box6040" && pallet.Type != 2)
            {
                errorMsg = "逻辑分区与料箱不匹配";
                return null;
            }

            TCell allocateCell = null;

            return allocateCell;
        }


        public List<string> GetAllReceivingOrderSn(int pageIndex, int pageSize)
        {
            // 创建一个空列表来存储分页后的结果
            List<string> result = new List<string>();

            // 获取所有接收订单详情数据，并筛选出状态为1的记录
            var receivingList = Context.TReceivingOrderDetails
                                    .Where(x => x.Status == 1)
                                    .Select(x => x.OrderSn)
                                    .Distinct()
                                    .ToList();

            // 使用LINQ对订单号进行分组
            var groupedOrderSns = receivingList
                                    .GroupBy(x => x)
                                    .Select(group => group.Key)
                                    .ToList();

            //// 对分组后的结果进行分页
            //var paginatedOrderSns = groupedOrderSns
            //                            .Skip((pageIndex - 1) * pageSize)
            //                            .Take(pageSize)
            //                            .ToList();

            // 将分页后的结果添加到结果列表中
            result.AddRange(groupedOrderSns);

            return result;
        }
        public ReceivingSelectDto GetReceivingByOrderSn(string OrderSn)
        {
            ReceivingSelectDto selectDto = new ReceivingSelectDto();
            selectDto.OrderSn = OrderSn;

            List<TReceivingOrderDetail> list = Context.TReceivingOrderDetails.Where(x => x.OrderSn == OrderSn && x.Status != 3).ToList();
            if (list.Count == 0)
            {
                return null;
            }
            selectDto.ReceivingOrderDetails = list;
            var settings = new JsonSerializerSettings
            {
                ContractResolver = new DefaultContractResolver
                {
                    NamingStrategy = new CustomCamelCaseNamingStrategy() // 使用自定义的大驼峰命名策略
                }
            };
            
            string json = JsonConvert.SerializeObject(list, settings);
            Console.WriteLine(json);
            return selectDto;
        }
        /// <summary>

        /// 提交（有网）
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool UpdRecevingStatus(ReceivingInternetDto dto, out string message)
        {
            message = "";
            using var tran = Context.Database.BeginTransaction();
            try
            {
                var receivingList = Context.TReceivingOrderDetails.Where(x => x.OrderSn == dto.OrderSn).ToList();
                if (receivingList.All(x => x.Status != 1))
                {
                    message = "入库单状态未审批或已完成";
                    return false;
                }
                //var InventoryList = Context.TInventories.Where(x => x.MaterialCode == dto.MaterialCode).ToList();
                //if (InventoryList.Count() > 0)
                //{
                //    //InventoryList.First().LocationCode = dto.Position;
                //    Context.TInventories.Update(InventoryList.First());

                //    if (Context.SaveChanges() <= 0)
                //    {
                //        tran.Rollback();
                //        message = "更新仓位失败";
                //        return false;
                //    }
                //}
                string ReceivingPoint = "";
                //var TInventoryList = Context.TInventories.Where(x => x.MaterialCode == dto.MaterialCode).ToList();
                TInventoryLog inventoryLog = new TInventoryLog();
                inventoryLog.SourceType = 0;
                ReceivingPoint = dto.Position;
                inventoryLog.SourceSn = dto.OrderSn;
                string mes = "";

                var inventoryList = Context.TInventories.Where(x => x.MaterialCode == dto.MaterialCode).ToList();
                if (inventoryList.Count() == 0)
                {
                    //查询库里是否有这个物料
                    if (SelectMaterial(dto.MaterialCode) == false)
                    {
                        if (!tReceivingOrderDetailRepository.DoesItExistMaterial(dto.OrderSn, ReceivingPoint, dto.Position, out mes))
                        {
                            tran.Rollback();
                            message = mes;
                            return false;
                        }
                    }


                }

                decimal? invenQty = 0;

              

                var invenList = Context.TMaterial.Where(x => x.Code == dto.MaterialCode).ToList();
                if (invenList.Count <= 0)
                {
                    tran.Rollback();
                    message = "物料" + dto.MaterialCode + "未添加到物料表中";
                    return false;
                }


                if (inventoryList.Count() > 0)
                {

                    var invenrotyPointList = inventoryList.Where(x => x.LocationCode == dto.Position).ToList();
                    if (invenrotyPointList.Count() > 0)
                    {
                        invenrotyPointList.First().AvailableQty = invenrotyPointList.First().AvailableQty += dto.ReceivedQty;

                        Context.Update(invenrotyPointList.First());
                    
                    }
                    else
                    {
                        TInventory inventoryAddList = new TInventory();
                        var cellList = Context.TCells.Where(x => x.Code == dto.Position).ToList();

                        if (cellList.Count() <= 0)
                        {
                            tran.Rollback();
                            message = "未查询到入库库位，请确认库位是否存在";
                            return false;
                        }
                        inventoryAddList.LocationCode = dto.Position;
                        inventoryAddList.LocationId = cellList.First().Id;
                        inventoryAddList.LocationName = cellList.First().Name;
                        inventoryAddList.LocationDepth = cellList.First().DepthIndex;
                        inventoryAddList.LocationLineNo = cellList.First().LineNo;
                        inventoryAddList.LocationLayerNo = cellList.First().LayerNo;
                        inventoryAddList.LocationColumnNo = cellList.First().ColumnNo;
                        inventoryAddList.Status = 1;
                        inventoryAddList.PalletBarcode = dto.PalletBarcode;
                        inventoryAddList.IsLock = false;
                        inventoryAddList.CreateDate = DateTime.Now;
                        inventoryAddList.MaterialId = invenList.FirstOrDefault().Id;
                        inventoryAddList.MaterialCode = dto.MaterialCode;
                        inventoryAddList.MaterialName = dto.Name;
                        inventoryAddList.AvailableQty = dto.ReceivedQty;
                        if (dto.UnitId <= 0)
                        {
                            inventoryAddList.UnitId = 0;
                            inventoryAddList.UnitName = "";
                            inventoryAddList.QualityState = 1;
                        }
                        else
                        {
                            inventoryAddList.UnitId = dto.UnitId;
                            inventoryAddList.UnitName = dto.UnitName;
                            inventoryAddList.QualityState = 1;
                        }
                        inventoryAddList.UnitId = dto.UnitId;
                        inventoryAddList.UnitName = dto.UnitName;
                        inventoryAddList.InStockDate = DateTime.Now;
                        inventoryAddList.QualityState = dto.QualityState;
                        inventoryAddList.MaterialCategoryId = dto.MaterialCategoryId;
                        inventoryAddList.MaterialCategoryCode = dto.MaterialCategoryCode;
                        inventoryAddList.MaterialCategoryName = dto.MaterialCategoryName;
                        inventoryAddList.Price = dto.Price;
                        inventoryAddList.PalletBarcode = dto.PalletBarcode;
                        inventoryAddList.ModelSpec = dto.ModelSpec;
                        Context.TInventories.Add(inventoryAddList);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            message = "添加库存信息失败";
                            return false;
                        }

                    }

                }
                else
                {
                    TInventory inventory1 = new TInventory();
                    var cellList = Context.TCells.Where(x => x.Code == dto.Position).ToList();
                    if (cellList.Count() <= 0)
                    {
                        tran.Rollback();
                        message = "未查询到入库库位，请确认库位是否存在";
                        return false;
                    }
                    var materialList = Context.TMaterial.Where(x => x.Code == dto.MaterialCode).ToList();
                    if (materialList.Count() <= 0)
                    {
                        tran.Rollback();
                        message = "未查询到物料" + dto.MaterialCode;
                        return false;
                    }
                    inventory1.LocationCode = dto.Position;
                    inventory1.LocationId = cellList.First().Id;
                    inventory1.LocationName = cellList.First().Name;
                    inventory1.LocationDepth = cellList.First().DepthIndex;
                    inventory1.LocationLineNo = cellList.First().LineNo;
                    inventory1.LocationLayerNo = cellList.First().LayerNo;
                    inventory1.LocationColumnNo = cellList.First().ColumnNo;
                    inventory1.Status = 1;
                    inventory1.PalletBarcode = dto.PalletBarcode;
                    inventory1.IsLock = false;
                    inventory1.CreateDate = DateTime.Now;
                    inventory1.MaterialId = materialList.FirstOrDefault().Id;
                    inventory1.MaterialCode = dto.MaterialCode;
                    inventory1.MaterialName = dto.Name;
                    inventory1.AvailableQty = dto.ReceivedQty;
                    if (dto.UnitId <= 0)
                    {
                        inventory1.UnitId = 0;
                        inventory1.UnitName = "";
                        inventory1.QualityState = 1;
                    }
                    inventory1.UnitId = dto.UnitId == 0 ? 0 : dto.UnitId;
                    inventory1.UnitName = dto.UnitName == null ? "" : dto.UnitName;
                    inventory1.InStockDate = DateTime.Now;
                    inventory1.QualityState = dto.QualityState;
                    inventory1.MaterialCategoryId = dto.MaterialCategoryId;
                    inventory1.MaterialCategoryCode = dto.MaterialCategoryCode;
                    inventory1.MaterialCategoryName = dto.MaterialCategoryName;
                    inventory1.Price = dto.Price;
                    inventory1.PalletBarcode = dto.PalletBarcode;
                    inventory1.ModelSpec = dto.ModelSpec;
                    Context.TInventories.Add(inventory1);
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        message = "添加库存信息失败";
                        return false;
                    }

                }


                var inventory = Context.TInventories.Where(x => x.MaterialCode == dto.MaterialCode && x.LocationCode == dto.Position).ToList();
                if (inventory.Count() > 0)
                {
                    TInventory inventory1 = inventory[0];
                    inventoryLog.WarehouseId = inventory1.WarehouseId;
                    inventoryLog.WarehouseName = inventory1.WarehouseName;
                    inventoryLog.LocationCode = inventory1.LocationCode;
                    inventoryLog.PalletBarcode = inventory1.PalletBarcode;
                    inventoryLog.MaterialId = inventory1.MaterialId;
                    inventoryLog.MaterialCode = inventory1.MaterialCode;
                    inventoryLog.MaterialName = inventory1.MaterialName;
                    inventoryLog.BaseUnitId = dto.UnitId;
                    inventoryLog.BaseUnitName = dto.UnitName;
                    //原始数量
                    inventoryLog.StartQty = inventory1.AvailableQty == null ? 0 : inventory1.AvailableQty - dto.ReceivedQty;
                    invenQty = inventory1.AvailableQty == null ? 0 : inventory1.AvailableQty - dto.ReceivedQty;
                    //变更数量
                    inventoryLog.ChangeQty = dto.ReceivedQty;
                    //最终数量
                    //inventory.AvailableQty = inventory.AvailableQty == null ? 0 + dto.ReceivedQty : inventory.AvailableQty + dto.ReceivedQty;

                    inventoryLog.EndQty = invenQty + dto.ReceivedQty;
                    inventoryLog.CreateDate = DateTime.Now;
                    Context.TInventoryLogs.Add(inventoryLog);
                }



                var ReceivingOrderDetailList = Context.TReceivingOrderDetails.Where(x => x.OrderSn == dto.OrderSn && x.MaterialCode == dto.MaterialCode).ToList();
                tReceivingOrderDetailRepository.IsInventoryWarn(inventoryList);

                foreach (var ReceivingOrderDetail in ReceivingOrderDetailList)
                {
                    if(dto.Qty - dto.ReceivedQty <= 0)
                    {
                        ReceivingOrderDetail.Status = 3;
                        Context.TReceivingOrderDetails.Update(ReceivingOrderDetail);
                    }
                    else
                    {
                        ReceivingOrderDetail.Qty = dto.Qty - dto.ReceivedQty;
                        Context.TReceivingOrderDetails.Update(ReceivingOrderDetail);
                    }
                    continue;
                }
                if (Context.SaveChanges() <= 0)
                {
                    tran.Rollback();
                    message = "更新失败";
                    return false;
                }

                //Context.TInventory.Update(inventory);

                tran.Commit();
                return true;

            }
            catch
            {
                tran.Rollback();
                message = "修改入库单失败";
                return false;
            }


        }

        public bool SelectMaterial(string materialCode)
        {

                var MaterialList = Context.TMaterial.Where(x => x.Code == materialCode).ToList();
                if (/*MaterialList != null &&*/ MaterialList.Count > 0)
                {
                    return true;
                }
                return false;

        }
    }
}




public class CustomCamelCaseNamingStrategy : NamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        // 将属性名转换为大驼峰命名
        return ToCamelCase(name);
    }

    private string ToCamelCase(string s)
    {
        if (string.IsNullOrEmpty(s))
            return s;

        if (!char.IsUpper(s[0]))
            return s;

        char[] chars = s.ToCharArray();
        for (int i = 0; i < chars.Length; i++)
        {
            if (i == 0 || (i < chars.Length - 1 && !char.IsUpper(chars[i + 1])))
            {
                chars[i] = char.ToUpper(chars[i]);
            }
            else
            {
                break;
            }
        }

        return new string(chars);
    }
}